/*
 *  Copyright (c) 2014 Lincong All rights reserved.
 *  This software is the confidential and proprietary information of Lincong.
 *  You shall not disclose such Confidential
 *  Information and shall use it only in accordance with the terms of the license
 *  agreement you entered into with Lincong.
 *   Mail: Lincong <lincong1987@gmail.com>
 *     QQ: 159257119
 *  Phone: 15925711961
 *  This File Created On 2014-1-17 23:18:22.
 *  Document   : firebird.controller-1.0.1
 *  Encoding   : UTF-8
 *  $Id$
 */

define(function (require, exports, module) {

	require("Firebird.Model");
	require("Firebird.ajax.Get");
	require("Firebird.ajax.Post");
	require("Firebird.ui.Dialog");

	/**
	 * 控制器
	 * @class Firebird.Controller
	 * @see Firebird.Model
	 */
	Firebird.define("Firebird.Controller", {
		extend: "Firebird.Model",
		statics: {
			_uuid: 1,
			uuid: function () {
				var s = [];
				var hexDigits = "0123456789abcdef";
				for (var i = 0; i < 36; i++) {
					s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
				}
				s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
				s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
				s[8] = s[13] = s[18] = s[23] = "-";
				return s.join("") + "" + this._uuid++;
			}
		},
		config: {
			controller: "{contextPath}/security/",
			mapping: {
				"main": "/main",
				"search": "/search",
				"get": "/get/{0}",
				"put": "/put",
				"post": "/post",
				"delete": "/delete/{0}",

				"save": "/save",
				"edit": "/edit/{0}",
				"view": "/view/{0}"
			},
			message: {
				"request:success": "请求成功",
				"request:error": "请求失败",
				"insert:success": "添加成功",
				"insert:error": "添加失败",
				"modify:success": "修改成功",
				"modify:error": "修改失败",
				"remove:success": "删除成功",
				"remove:error": "删除失败",
				"select:success": "查询成功",
				"select:error": "查询失败",
				"selectList:success": "查询成功",
				"selectList:error": "查询失败",
				"save:success": "新增成功",
				"save:error": "新增失败",
				"edit:success": "修改成功",
				"edit:error": "修改失败",
				"view:success": "查看成功",
				"view:error": "查看失败",
				"main:success": "列数据成功",
				"main:error": "列数据失败",
				"open:success": "打开成功",
				"open:error": "打开失败"
			}
		},
		constructor: function (config) {
			this.initConfig(config);
		},
		/**
		 * @method
		 * @param callback
		 */
		ready: function (callback) {
			callback && callback();
		},
		/**
		 * CLOSE
		 * @method
		 * @param data
		 */
		close: function (data) {
			var dialog = Firebird.ui.Dialog.get(window);
			dialog.close(data);
			dialog.remove();
		},
		getText: function (text) {
			var message = text || "";


			return message;
		},
		/**
		 * setButtons
		 * @param buttons
		 */
		setButtons: function (buttons) {
			var dialog = Firebird.ui.Dialog.get(window);
			dialog.button(buttons);
		},
		/**
		 * getAction 获取控制器的路径
		 * @method
		 * @param {String} name
		 * @param {Function} filter
		 * @returns {*}
		 */
		getAction: function (name, filter) {
			var filter = filter || function (url) {
					return url;
				};
			var mapping = this.getMapping()[name] || name;
			return this.buildRequest(this.getController().replace(/\{contextPath\}/, firebird.api.get("contextPath") || "") + filter(mapping));
		},
		/**
		 * buildRequest
		 * @private
		 * @param url
		 * @returns {{uuid: *, url: (*|String)}}
		 */
		buildRequest: function (url) {
			url = url.replace(/\{contextPath\}/, firebird.api.get("contextPath") || "");
			var uuid = this.getUUID();
			return {
				uuid: uuid,
				url: url
			};
		},
		/**
		 * getUUID
		 * @private
		 * @returns {string}
		 */
		getUUID: function () {
			return "__FBID__" + Firebird.Controller.uuid() + "-" + new Date().getTime();
		},
		/**
		 * 通过接口获取数据
		 *
		 * @method
		 * @param url
		 * @param options
		 * @param success
		 * @returns {jqXhr}
		 */
		request: function (url, options, success, error) {
			return Firebird.create("Firebird.ajax.Get", $.extend({}, {
					url: this.buildRequest(url).url,
					dataType: "json",
					success: function (data) {
						success && success(data);
					},
					error: function (jqXHR, textStatus, e) {
						Firebird.ui.Dialog.error("请求失败。", {});
						error && error(e);
					}
				},
				options)).xhr;
		},
		/**
		 * 插入数据
		 * @param {Object|FormData} data 需要插入的数据，一般为一个对象，也可以使用 $(form).serialize() 表单序列化
		 * @param {Object} options 可以覆盖insert方法中默认的ajax参数
		 * @param {Function} success 成功回调
		 * @param {Function} error 错误回调
		 * @returns {*} jQuery xhr对象
		 *
		 * @example
		 * <pre>
		 * // 例子来自 Security.User.SaveApp
		 * context.userController.insert($("#form1").serialize(), {}, function (data) {
         *      if (data.success === true) {
         *          context.dialog.close();
         *      }
         * });
		 * </pre>
		 */
		insert: function (data, options, success, error) {
			return Firebird.create("Firebird.ajax.Post", $.extend({}, {
				url: this.getAction("post").url,
				dataType: "json",
				data: data,
				success: function (data) {
					success && success(data);
				},
				error: function (jqXHR, textStatus, e) {
					Firebird.ui.Dialog.error("插入数据失败。", {});
					error && error(e);
				}
			}, options || {})).xhr;
		},
		/**
		 * 更新数据
		 * @param {Object|FormData} data 需要更新的数据，一般为一个对象，也可以使用 $(form).serialize() 表单序列化
		 * @param options {Object} options 可以覆盖insert方法中默认的ajax参数
		 * @param {Function} success 成功回调
		 * @param {Function} error 错误回调
		 * @returns {*}
		 */
		modify: function (data, options, success, error) {
			return Firebird.create("Firebird.ajax.Post", $.extend({}, {
				url: this.getAction("put").url,
				dataType: "json",
				data: data,
				success: function (data) {
					success && success(data);
				},
				error: function (jqXHR, textStatus, e) {
					Firebird.ui.Dialog.error("修改数据失败。", {});
					error && error(e);
				}
			}, options)).xhr;
		},
		/**
		 *  remove
		 *
		 * @param ids
		 * @param options
		 * @param {Function} success 成功回调
		 * @param {Function} error 错误回调
		 * @returns {*}
		 */
		remove: function (ids, options, success, error) {
			if (firebird.isArray(ids)) {
				ids = ids.join(",");
			}
			return Firebird.create("Firebird.ajax.Post", $.extend({}, {
				url: this.getAction("delete", function (url) {
					return Firebird.String.format(url, ids);
				}).url,
				dataType: "json",
				success: function (data) {
					success && success(data);
				},
				error: function (jqXHR, textStatus, e) {
					Firebird.ui.Dialog.error("删除数据失败。", {});
					error && error(e);
				}
			}, options)).xhr;
		},
		/**
		 * select
		 * @param id
		 * @param options
		 * @param {Function} success 成功回调
		 * @param {Function} error 错误回调
		 * @returns {*}
		 */
		select: function (id, options, success, error) {
			return Firebird.create("Firebird.ajax.Get", $.extend({}, {
				url: this.getAction("get", function (url) {
					return Firebird.String.format(url, id);
				}).url,
				dataType: "json",
				success: function (data) {
					success && success(data);
				},
				error: function () {
					$.dialog.error("获取数据失败。", {});
					error && error(e);
				}
			}, options)).xhr;
		},
		/**
		 * selectList
		 * @param page
		 * @param size
		 * @param options
		 * @param success
		 * @returns {*}
		 */
		selectList: function (page, size, options, success, error) {
			return Firebird.create("Firebird.ajax.Get", $.extend({}, {
					url: this.getAction("search", function (url) {
						return Firebird.String.format(url, page, size);
					}).url,
					dataType: "json",
					success: function (data) {
						success && success(data);
					},
					error: function () {
						Firebird.ui.Dialog.error("获取数据失败。", {});
						error && error(e);
					}
				},
				options)).xhr;
		},
		/**
		 * save方法，会打开一个iframe dialog
		 * @param {Object} options 打开窗口的配置，用json描述
		 * @param {Function} success  成功回调 success 带有1个参数 data
		 * @param {Function} error  失败回调
		 * @returns {*}
		 * @example
		 * @function Firebird.Controller#save
		 * <pre>
		 *     var controller = new Firebird.Controller({
         *          controller: "{contextPath}/user"
         *     });
		 *     // save 方法将会打开 {contextPath}/user/save
		 *     //
		 *     controller.save({
         *          // 这个是一个自定义的方法
         *          sayHelloToDialog: function(dataFromDialogWin){
         *             dataFromDialogWin.sayHello(window);
         *             // 你可以在这里操作目标窗口的内容
         *          }
         *     },
		 *     function(data){
         *          if(data.success === false){
         *              alert("Oops!");
         *          }
         *     },
		 *     function(e){
         *          alert(e instanceof Error);
         *          // true
         *          alert("Oops!");
         *     });
		 * </pre>
		 */
		save: function (options, success, error) {

			var req = this.getAction("save");
			var url = req.url;
			if (error) {
				options = options || {
						error: error
					};
			}
			firebird.data.set(req.uuid, options);
			var dialog = this.open(url, $.extend({}, {
					id: req.uuid,
					lock: true,
					onclose: function () {
						if (success) {
							success(this.returnValue, this);
						} else {
							if (this.returnValue && this.returnValue.success === true) {
								dialog.remove();
								Firebird.ui.Dialog.tips("数据添加成功！", 3000);
							}
						}
					}
				},
				options));
			return dialog;
		},
		/**
		 * edit
		 * @param id
		 * @param options
		 * @param {Function} success 成功回调
		 * @param {Function} error 错误回调
		 * @returns {*|unresolved}
		 */
		edit: function (id, options, success, error) {
			var req = this.getAction("edit", function (url) {
				return Firebird.String.format(url, id);
			});
			var url = req.url;
			if (error) {
				options = options || {
						error: error
					};
			}
			firebird.data.set(req.uuid, options);
			var dialog = this.open(url, $.extend({}, {
					id: req.uuid,
					lock: true,
					onclose: function () {
						if (success) {
							success(this.returnValue, this);
						} else {
							if (this.returnValue && this.returnValue.success === true) {
								dialog.remove();
								Firebird.ui.Dialog.tips("数据修改成功！", 3000);
							}
						}
					}
				},
				options));
			return dialog;
		},
		/**
		 * view
		 * @param options
		 * @returns {*|unresolved}
		 */
		view: function (id, options, success, error) {
			var req = this.getAction("view", function (url) {
				return Firebird.String.format(url, id);
			});
			var url = req.url;
			firebird.data.set(req.uuid, options);
			var dialog = this.open(url, $.extend({}, {
					id: req.uuid,
					lock: true,
					onclose: function () {
						if (success) {
							success(this.returnValue, this);
						} else {
							if (this.returnValue && this.returnValue.success === true) {
								dialog.remove();
							}
						}
					}
				},
				options));
			return dialog;
		},
		/**
		 * main
		 * @param options
		 * @returns {*}
		 */
		main: function (options, success) {
			var req = this.getAction("main");
			var url = req.url;
			firebird.data.set(req.uuid, options);
			var dialog = this.open(url, $.extend({}, {
					id: req.uuid,
					onclose: function () {
						if (success) {
							success(this.returnValue, this);
						} else {
							if (this.returnValue && this.returnValue.success === true) {
								dialog.remove();
								Firebird.ui.Dialog.tips("数据修改成功！", 3000);
							}
						}
					}
				},
				options));
			return dialog;
		},
		/**
		 * 打开窗口
		 * @param {String} url 需要打开的路径
		 * @param {Object} options
		 * @returns {*}
		 */
		open: function (url, options) {
			var req = this.getAction(url);
			firebird.data.set(req.uuid, options);
			return Firebird.ui.Dialog.open(url, $.extend({}, {id: req.uuid}, options));
		},
		/**
		 *  toString
		 * @returns {string}
		 */
		toString: function () {
			return [this.$className, "[", decodeURIComponent($.param(this.config).replace(/\&/g, ", ")), "]"].join(" ");
		}
	});

	module.exports = Firebird.Controller;
});